package org.example.filter;

import lombok.extern.slf4j.Slf4j;
import org.example.utils.JwtUtil;
import org.example.utils.Opt;
import org.springframework.core.Ordered;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import static org.example.constants.CommonConstants.API_INTERNAL_HEADER_NAME;

/**
 * InternalApiHandlerInterceptor 内部API请求拦截器
 * 用于拦截和验证内部API请求的合法性
 * 通过检查请求头中的内部API标识和验证API令牌来确保请求的安全性
 */
@Component
@Slf4j
public class InternalApiHandlerInterceptor implements HandlerInterceptor, Ordered {
    /**
     * 前置拦截方法
     * 在请求处理之前进行调用，用于验证内部API请求的合法性
     * @param request 当前HTTP请求对象
     * @param response 当前HTTP响应对象
     * @param handler 请求处理的方法对象
     * @return 如果验证通过返回true，否则返回false
     * @throws Exception 可能抛出的异常
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("InternalApiHandlerInterceptor preHandle");
        // 获取请求头中的内部API标识
        String apiHeader = request.getHeader(API_INTERNAL_HEADER_NAME);
        // 使用Optional包装请求头信息，避免空指针异常
        Opt<String> apiHeaderOpt = Opt.of(apiHeader);
        // 检查请求头是否存在
        if(!apiHeaderOpt.isPresent()) {
            log.info("internal api header not present,url:{}", request.getRequestURI());
            response.sendError(401, "internal api header not present");
            return false;
        }
        // 获取请求头值并进行令牌验证
        String apiHeaderValue = apiHeaderOpt.get();
        if(!JwtUtil.verifyApiToken(apiHeaderValue)) {
            log.info("internal api token verification failed,url:{}", request.getRequestURI());
            response.sendError(401, "internal api token verification failed");
            return false;
        }
        return true;
    }

    /**
     * 后置处理方法
     * 在请求处理之后，视图渲染之前进行调用
     * @param request 当前HTTP请求对象
     * @param response 当前HTTP响应对象
     * @param handler 请求处理的方法对象
     * @param modelAndView 视图和模型对象，可能为null
     * @throws Exception 可能抛出的异常
     */
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    /**
     * 完成处理方法
     * 在整个请求完成后进行调用，即在视图渲染之后
     * @param request 当前HTTP请求对象
     * @param response 当前HTTP响应对象
     * @param handler 请求处理的方法对象
     * @param ex 处理过程中抛出的异常，如果没有异常则为null
     * @throws Exception 可能抛出的异常
     */
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }


    @Override
    public int getOrder() {
        return 10;
    }
}
